﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Threading;
using Microsoft.Phone.BackgroundAudio;
using Microsoft.Practices.ServiceLocation;
using SAFPodcast.WP8.DAL.FileSystem;
using SAFPodcast.WP8.DTO.Entities;
using SAFPodcast.WP8.DTO.TO;
using SAFPodcast.WP8.Fwk.BackgroundAudio;
using SAFPodcast.WP8.Fwk.Helper;
using SAFPodcast.WP8.Fwk.IO;
using SAFPodcast.WP8.Model.Services;

namespace SAFPodcast.WP8.ViewModel
{
    public class ViewFeedViewModel : ViewModelBase
    {
        private IDataService _dataService;
        private bool canDownload;
        private object syncLock;

        public ViewFeedViewModel(IDataService dataService)
        {
            _dataService = dataService;
            syncLock = new object();

            canDownload = true;

            play = new RelayCommand<FeedItem>(PlayMethod);
            download = new RelayCommand<FeedItem>(DownloadMethod);
        }

        #region FeedItems
        public const string FeedItemsPropertyName = "FeedItems";
        private ObservableCollection<FeedItem> feedItems = null;
        public ObservableCollection<FeedItem> FeedItems
        {
            get
            {
                return feedItems;
            }
            set
            {
                Set(FeedItemsPropertyName, ref feedItems, value);
            }
        }
        #endregion
        #region Download
        private RelayCommand<FeedItem> download;
        public RelayCommand<FeedItem> Download
        {
            get
            {
                return download;
            }
        }

        private void DownloadMethod(FeedItem item)
        {
            if (canDownload)
            {
                lock (syncLock)
                {
                    if (canDownload)
                    {
                        _dataService.DownloadFeedItem(item, DownloadMethodCallback);
                        canDownload = false;
                    }
                }
            }
        }

        private void DownloadMethodCallback(DownloadFeedItemDataItem dataItem, Exception ex)
        {
            if (ex == null)
            {
                if (dataItem.Canceled)
                {
                    dataItem.FeedItem.DownloadProgress = 0;
                    dataItem.FeedItem.IsDownloading = false;
                    canDownload = true;
                }
                else
                {
                    dataItem.FeedItem.IsDownloading = true;
                    dataItem.FeedItem.DownloadProgress = dataItem.Completion;
                    if (dataItem.Stream != null)
                    {
                        var copier = new FileCopier(
                            dataItem.Stream,
                            Path.Combine(Guid.NewGuid().ToString() + ".mp3"),
                            dataItem.Song,
                            (a) => DispatcherHelper.RunAsync(a),
                            FileSystemAccessObject.WriteFile);
                        copier.CopyCompleted += (src, e) =>
                        {
                            canDownload = true;
                            dataItem.FeedItem.IsDownloading = false;
                        };
                        copier.Run();
                    }
                }
            }
            else
            {
                LogHelper.Error("Erreur lors du téléchargement d'un fichier depuis la liste", ex);
                canDownload = true;
                dataItem.FeedItem.IsDownloading = false;
            }
        }
        #endregion
        #region Play
        private RelayCommand<FeedItem> play;
        public RelayCommand<FeedItem> Play
        {
            get
            {
                return play;
            }
        }
        private void PlayMethod(FeedItem item)
        {
            BackgroundAudioPlayer.Instance.PlayTrack(
                item.Uri,
                item.Title,
                item.Feed.Name,
                item.Feed.Name);
        }
        #endregion
        #region SelectedFeed
        public const String SelectedFeedPropertyName = "SelectedFeed";
        private Feed selectedFeed = null;
        public Feed SelectedFeed
        {
            get
            {
                return selectedFeed;
            }
            set
            {
                Set(SelectedFeedPropertyName, ref selectedFeed, value);
            }
        }
        #endregion
        #region FeedName
        public String FeedName
        {
            get
            {
                return selectedFeed == null ? String.Empty : selectedFeed.Name;
            }
        }
        #endregion
    }
}
